﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../global/head.h"
#include "../impl/head.h"
#include "../macro/head.h"
#include "aio_key.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos_aio
{
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static aio_key::POOL * pool_ptr = 0;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    aio_key::aio_key()
    {
        memset( &m_remote_addr, 0, sizeof( m_remote_addr ) );
        memset( &m_local_addr, 0, sizeof( m_local_addr ) );
        m_eState = KEY_STATE_NONE;
        m_nEpollFlags = 0;
        m_nRequestNum = 0;
        m_bCanWrite = false;
        m_enumHandleType = H_TYPE_NONE;
        m_pSocket = 0;
        m_lpUserKey = 0;
        m_lpMsg = 0;
        m_nLastInstance = 0;
        m_nInstance = 0;
    }

    aio_key::~aio_key()
    {
        term();
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int aio_key::helper_finish_request( aio_impl * lpAioImpl, aio_data::LIST & data_list )
    {
        int nRet = 0;

        for( aio_data::ITER i = data_list.begin(); i != data_list.end(); ++i )
        {
            aio_data * lpData = *i;
            xos_box::i_msg * lpMsg = lpData->m_pMsg;
            lpData->m_pMsg = 0;
            lpData->release();
            lpData = 0;
            lpMsg->set_bool( 0, false );
            lpAioImpl->notify( lpMsg );
        }

        data_list.clear();

        return nRet;
    }

    int aio_key::clear_recv_list( aio_data::LIST & recv_list )
    {
        int nRet = 0;

        for( aio_data::ITER i = recv_list.begin(); i != recv_list.end(); ++i )
        {
            aio_data * lpData = *i;
            xos_box::i_msg * lpMsg = lpData->m_pMsg;
            lpData->m_pMsg = 0;
            lpData->release();
            lpData = 0;
            xos_box::i_buf * lpBuf = lpMsg->get_buf( 0, 0 );

            if( lpBuf )
            {
                lpBuf->release();
                lpBuf = 0;
            }

            lpMsg->release();
            lpMsg = 0;
        }

        recv_list.clear();

        return nRet;
    }

    int aio_key::get_addr( POOL *** pppPool, LIST *** pppList )
    {
        int ret = 0;
        if( pppPool )
        {
            *pppPool = &pool_ptr;
        }
        if( pppList )
        {
            *pppList = 0;
        }
        return ret;
    }

    int aio_key::finish_request( aio_impl * lpAioImpl )
    {
        int nRet = 0;
        
        helper_finish_request( lpAioImpl, m_pend_accept_list );
        helper_finish_request( lpAioImpl, m_pend_recv_list );
        helper_finish_request( lpAioImpl, m_pend_send_list );
        m_eState = KEY_STATE_CLOSED;

        return nRet;
    }

    int aio_key::init()
    {
        using namespace std;
        int nRet = 0;
        return nRet;
    }

    int aio_key::term()
    {
        int nRet = 0;

        m_pend_accept_list.put_back_to_pool( true );
        m_pend_recv_list.put_back_to_pool( true );
        m_pend_send_list.put_back_to_pool( true );
        m_accept_list.put_back_to_pool( true );
        clear_recv_list( m_recv_list );

        memset( &m_remote_addr, 0, sizeof( m_remote_addr ) );
        memset( &m_local_addr, 0, sizeof( m_local_addr ) );
        m_eState = KEY_STATE_NONE;
        m_nEpollFlags = 0;
        m_nRequestNum = 0;
        m_bCanWrite = false;
        m_enumHandleType = H_TYPE_NONE;
        m_lpUserKey = 0;
        m_lpMsg = 0;

        m_nInstance = !m_nInstance;

        if( m_pSocket )
        {
            m_pSocket->release();
            m_pSocket = 0;
        }

        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int aio_key::release()
    {
        int nRet = 0;

        term();
		put_back_to_pool( this, true );

        return nRet;
    }

} // xos_aio
